#include "CircleView.h"

namespace poly
{
	const DWORD CircleView::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;
	const uint32 CircleView::vertexSize = sizeof(float3) + sizeof(DWORD);

	CircleView::CircleView(poly::D3DDevice device ) :
		m_device( device ), m_radius( 1 ), m_segments( 3 ), m_color( 1.f, 0.f, 0.f, 0.f ),
		m_vertexBuffer( 0 )
	{
	}

	void CircleView::initialize(poly::D3DDevice device)
	{
		m_device = device;
		SAFE_RELEASE( m_vertexBuffer );
	}

	CircleView::~CircleView()
	{
		destroy();
	}

	void CircleView::destroy()
	{
		m_device = 0;
		SAFE_RELEASE( m_vertexBuffer );
	}

	void CircleView::setup( float radius, uint32 segments, float4 const & c )
	{
		m_radius = radius;
		m_segments = segments;
		m_color = c;

		SAFE_RELEASE( m_vertexBuffer );
		if( m_device != 0 )
		{
			uint32 byteLength = (segments + 2)*vertexSize;
			if( byteLength == 0 ) return;
			m_device->CreateVertexBuffer(
				byteLength,
				0, // usage
				FVF,
				D3DPOOL_MANAGED,
				&m_vertexBuffer,
				0 );

			uint8 * data;
			m_vertexBuffer->Lock( 0, 0, (void**)& data, 0 );

			D3DCOLOR diffuse = D3DCOLOR_ARGB(
				(uint32)(m_color.x * 255),
				(uint32)(m_color.y * 255),
				(uint32)(m_color.z * 255),
				(uint32)(m_color.w * 255) );

			float3 vertex( 0.f, 0.f, 0.f );
			memcpy( data, &vertex, sizeof(float3) );
			data += sizeof(float3);
			memcpy( data, &m_color, sizeof(D3DCOLOR) );
			data += sizeof(D3DCOLOR);
			for( int i = 0; i < m_segments; i++ )
			{
				float3 vertex( cos(TWO_PI*i/segments), sin(TWO_PI*i/segments), 0 );
				memcpy( data, &vertex, sizeof(float3) );
				data += sizeof(float3);
				memcpy( data, &m_color, sizeof(D3DCOLOR) );
				data += sizeof(D3DCOLOR);
			}
			vertex = float3( 1.f, 0.f, 0.f );
			memcpy( data, &vertex, sizeof(float3) );
			data += sizeof(float3);
			memcpy( data, &m_color, sizeof(D3DCOLOR) );
			data+= sizeof(D3DCOLOR);

			m_vertexBuffer->Unlock();
		}
	}

	void CircleView::render( float44 const & world )
	{
		if( m_vertexBuffer == 0 )
			return;

		m_device->SetTransform( D3DTS_WORLD, &world );
		m_device->SetStreamSource( 0, m_vertexBuffer, 0, vertexSize );
		m_device->SetFVF( FVF );
		m_device->SetRenderState( D3DRS_LIGHTING, FALSE );

		m_device->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, m_segments );
	}
}
